package be.jaisy.osgi.console.service.util;

import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogEntry;
import org.osgi.service.log.LogService;

import be.jaisy.osgi.console.service.api.to.BundleTo;
import be.jaisy.osgi.console.service.api.to.LogEntryTo;
import be.jaisy.osgi.console.service.api.to.OsgiServiceTo;
import be.jaisy.osgi.util.DateHelper;

public class ConsoleHelper {
	
	private static final String HEADER_VERSION = "Bundle-Version";
	private static final String HEADER_VENDOR = "Bundle-Vendor";
	
	@SuppressWarnings("restriction")
	public static BundleTo convert(Bundle bundle){
		if(bundle==null)
			return null;
		BundleTo bundleTo = new BundleTo();
		bundleTo.setBundleId(bundle.getBundleId());
		bundleTo.setSymbolicName(bundle.getSymbolicName());
		bundleTo.setVersion(String.valueOf(bundle.getHeaders(null).get(HEADER_VERSION)));
		bundleTo.setState(ConsoleHelper.getStateName(bundle));
		bundleTo.setVendor(String.valueOf(bundle.getHeaders(null).get(HEADER_VENDOR)));
		return bundleTo;
	}
	
	/**
	 * Given a state value, return the string describing that state.
	 * 
	 * @param Bundle
	 *            An Bundle containing a state value
	 * @return A String describing the state
	 */
	public static String getStateName(Bundle bundle) {
		int state = bundle.getState();
		switch (state) {
		case Bundle.UNINSTALLED:
			return "UNINSTALLED"; //$NON-NLS-1$
		case Bundle.INSTALLED:
			return "INSTALLED"; //$NON-NLS-1$
		case Bundle.RESOLVED:
			return "RESOLVED"; //$NON-NLS-1$
		case Bundle.STARTING:
			return "STARTING"; //$NON-NLS-1$
		case Bundle.STOPPING:
			return "STOPPING"; //$NON-NLS-1$
		case Bundle.ACTIVE:
			return "ACTIVE"; //$NON-NLS-1$
		default:
			return "UNKNOWN["+Integer.toHexString(state)+"]";//$NON-NLS-1$
		}
	}
	
	private static String SERVICE_KEY_INSTANCES = Constants.OBJECTCLASS; 
	private static String SERVICE_KEY_ID = Constants.SERVICE_ID; 
	//private static String SERVICE_KEY_PID = Constants.SERVICE_PID; 
	private static String SERVICE_KEY_RANKING = Constants.SERVICE_RANKING; 
	private static String SERVICE_KEY_VENDOR = Constants.SERVICE_VENDOR; 
	private static String SERVICE_KEY_DESCRIPTION = Constants.SERVICE_DESCRIPTION; 
	
	@SuppressWarnings("unchecked")
	public static OsgiServiceTo convert(ServiceReference serviceReference) {
		OsgiServiceTo osgiServiceTo = new OsgiServiceTo();
		osgiServiceTo.setId((Long)serviceReference.getProperty(SERVICE_KEY_ID));
		osgiServiceTo.setInterfaceClassNames((String[])serviceReference.getProperty(SERVICE_KEY_INSTANCES));
		osgiServiceTo.setRanking((Integer)serviceReference.getProperty(SERVICE_KEY_RANKING));
		osgiServiceTo.setVendor((String)serviceReference.getProperty(SERVICE_KEY_VENDOR));
		osgiServiceTo.setDescription((String)serviceReference.getProperty(SERVICE_KEY_DESCRIPTION));
		osgiServiceTo.setRegisteredBundleid(serviceReference.getBundle().getBundleId());
		if (serviceReference.getUsingBundles() != null) {
			Bundle[] usedByBundle = serviceReference.getUsingBundles();
			Long[] usedByBundleIds = new Long[usedByBundle.length];
			for (int i = 0; i < usedByBundle.length; i++) {
				usedByBundleIds[i] = usedByBundle[i].getBundleId();
			}
			osgiServiceTo.setUsedByBundleIds(usedByBundleIds);
		}		
		return osgiServiceTo;
	}
	
	public static LogEntryTo convert(LogEntry logEntry){
		LogEntryTo logEntryTo = new LogEntryTo();
		logEntryTo.setBundleId(logEntry.getBundle().getBundleId());
		logEntryTo.setException(logEntry.getException());
		logEntryTo.setLevel(ConsoleHelper.getLevelName(logEntry));
		logEntryTo.setMessage(logEntry.getMessage());
		if(logEntry.getMessage()==null && logEntry.getException()!=null)
			logEntryTo.setMessage(logEntry.getException().getMessage());
		if(logEntry.getServiceReference()!=null)
			logEntryTo.setOsgiServiceName(logEntry.getServiceReference().toString());
		logEntryTo.setTime(DateHelper.getTime(logEntry.getTime()));
		return logEntryTo;
	}
	
	/**
	 * Given a level value, return the string describing that level.
	 * 
	 * @param Bunedle
	 *            An Bunedle containing a level value
	 * @return A String describing the level
	 */
	public static String getLevelName(LogEntry logEntry) {
		int level = logEntry.getLevel();
		switch (level) {
		case LogService.LOG_DEBUG:		
			return "DEBUG"; //$NON-NLS-1$
		case LogService.LOG_INFO:
			return "INFO"; //$NON-NLS-1$
		case LogService.LOG_WARNING:
			return "WARNING"; //$NON-NLS-1$
		case LogService.LOG_ERROR:
			return "ERROR"; //$NON-NLS-1$
		default:
			return "UNKNOWN["+Integer.toHexString(level)+"]";//$NON-NLS-1$
		}
	}

}
